package com.learning.platform.service;

import com.learning.platform.dto.CertificateResponse;
import com.learning.platform.entity.Certificate;
import com.learning.platform.enums.CertificateStatus;
import com.learning.platform.enums.CertificateTemplate;
import com.learning.platform.exception.BusinessException;
import com.learning.platform.repository.CertificateRepository;
import com.learning.platform.security.UserPrincipal;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Optional;
import java.util.UUID;

@Service
@Transactional
public class CertificateService {
    
    private final CertificateRepository certificateRepository;
    
    public CertificateService(CertificateRepository certificateRepository) {
        this.certificateRepository = certificateRepository;
    }
    
    /**
     * 生成证书
     */
    public CertificateResponse generateCertificate(Long userId, Long courseId, String courseName, 
                                                 BigDecimal completionRate, BigDecimal finalScore, 
                                                 UserPrincipal issuer) {
        // 检查是否已存在证书
        if (certificateRepository.existsByUserIdAndCourseId(userId, courseId)) {
            throw new BusinessException("该用户已获得此课程证书");
        }
        
        Certificate certificate = new Certificate();
        certificate.setUserId(userId);
        certificate.setCourseId(courseId);
        certificate.setCertificateNumber(generateCertificateNumber());
        certificate.setCertificateName(courseName + "结业证书");
        certificate.setIssueDate(LocalDate.now());
        certificate.setCompletionRate(completionRate);
        certificate.setFinalScore(finalScore);
        certificate.setVerificationCode(generateVerificationCode());
        certificate.setTemplateType(determineTemplate(finalScore));
        certificate.setStatus(CertificateStatus.ACTIVE);
        certificate.setIssuedBy(issuer.getUserId());
        
        Certificate saved = certificateRepository.save(certificate);
        return new CertificateResponse(saved);
    }
    
    /**
     * 获取证书详情
     */
    @Transactional(readOnly = true)
    public CertificateResponse getCertificate(Long id) {
        Certificate certificate = certificateRepository.findById(id)
                .orElseThrow(() -> new BusinessException("证书不存在"));
        
        return new CertificateResponse(certificate);
    }
    
    /**
     * 获取用户证书列表
     */
    @Transactional(readOnly = true)
    public Page<CertificateResponse> getUserCertificates(Long userId, Pageable pageable) {
        return certificateRepository.findByUserId(userId, pageable)
                .map(CertificateResponse::new);
    }
    
    /**
     * 验证证书
     */
    @Transactional(readOnly = true)
    public CertificateResponse validateCertificate(String certificateNumber, String verificationCode) {
        Optional<Certificate> certificate = certificateRepository.validateCertificate(certificateNumber, verificationCode);
        if (certificate.isEmpty()) {
            throw new BusinessException("证书验证失败");
        }
        
        return new CertificateResponse(certificate.get());
    }
    
    /**
     * 撤销证书
     */
    public void revokeCertificate(Long id, UserPrincipal currentUser) {
        Certificate certificate = certificateRepository.findById(id)
                .orElseThrow(() -> new BusinessException("证书不存在"));
        
        certificate.setStatus(CertificateStatus.REVOKED);
        certificateRepository.save(certificate);
    }
    
    /**
     * 生成证书编号
     */
    private String generateCertificateNumber() {
        return "CERT" + System.currentTimeMillis();
    }
    
    /**
     * 生成验证码
     */
    private String generateVerificationCode() {
        return UUID.randomUUID().toString().replace("-", "").substring(0, 16).toUpperCase();
    }
    
    /**
     * 根据成绩确定证书模板
     */
    private CertificateTemplate determineTemplate(BigDecimal finalScore) {
        if (finalScore == null) {
            return CertificateTemplate.BASIC;
        }
        
        if (finalScore.compareTo(new BigDecimal("90")) >= 0) {
            return CertificateTemplate.PROFESSIONAL;
        } else if (finalScore.compareTo(new BigDecimal("80")) >= 0) {
            return CertificateTemplate.ADVANCED;
        } else {
            return CertificateTemplate.BASIC;
        }
    }
}
